package 力扣.双指针.最长区间;


import org.omg.CORBA.INTERNAL;

import java.util.HashMap;
import java.util.HashSet;

public class 水果成篮904 {
    /**
     * 给定一个数组 A[]，请你找到一个最长区间，这个区间里面最多包含两个不一样的数。
     *
     * 输入：A = [1, 2, 1, 2, 3]
     *
     * 输出：4
     *
     * 解释：区间 [1, 2, 1, 2] 里面只有两个数，并且是最长区间。
     */

    /**
     维持一个大小为2滑动窗口，并对窗口内的元素计数。
     若窗口中的元素个数大于2，需要移动left指针
     移动left指针直到tree[left] = 0，则说明这个窗口里面只剩下两个元素了

     如何维护一个长度为2的窗口呢，并且可以对窗口内的元素进行计数？
     创建一个继承了HashMap的计数器类即可，增强get方法、put方法
     */
    public int totalFruit(int[] tree) {
          if (tree == null || tree.length == 0){
              return 0;
          }
          int ans = 0;
          int left = -1;
          int N = tree.length;
          Counter counter = new Counter();
        for (int i = 0; i < N; i++) {
            int x = tree[i];
            counter.add(x,1);
            while (counter.size() > 2){//说明超过两个元素了
                //移除最左边的元素
                int t = tree[++left];
                counter.add(t, -1);
//                if (counter.getC(t) == 0){//直到第三者被移除
//                    counter.remove(t);
//                }
            }
            ans = Math.max(ans, i - left);
        }
        return ans;
    }

    /**
     * HashMap计数器
     */
    class Counter extends HashMap{
          public int get (int key){
              return containsKey(key) ? (int) super.get(key) : 0;
          }
          public void add(int key,int value){
              put(key, get(key) + value);
              if (get(key) <= 0){
                  remove(key);
              }
          }
    }


    public  int totalFruit2(int[] tree) {
           if(tree == null || tree.length == 0){
               return 0;
           }
           int N = tree.length;
        Counter counter = new Counter();
        int left = -1;
        int ans = 0;
        for (int i = 0; i < N; i++) {
            int t = tree[i];
            counter.add(t, 1);
            while (counter.size() > 2){
                counter.add(++left,-1);
            }
            ans = Math.max(ans, i - left);
        }
        return ans;
    }
}
